﻿using System;
using System.Diagnostics;
using System.IO;

namespace tool
{
    using System.Xml;
    using System.Timers;
    using System.Collections.Generic;
    
    public class CTimer
    {
        internal enum FLAG
        {
            NONE,
            RUNING,
            TIME_OUT,
        };

        public delegate void FuncOnTimeOut();
        protected System.Timers.Timer m_timer;
        protected FuncOnTimeOut _OnTimeOut;
        internal FLAG m_flag;

        public CTimer(FuncOnTimeOut func)
        {
            _OnTimeOut = func;
            m_flag = FLAG.NONE;
        }

        public bool IsTimeOut()
        {
            return (m_flag == FLAG.TIME_OUT);
        }

        public void SetTimerFlagRun()
        {
            m_flag = FLAG.RUNING;
        }

        public void BeginTimer(uint uSecond, bool bAutoReset)
        {
            try
            {
                m_flag = FLAG.RUNING;
                m_timer = new Timer(uSecond * 1000);
                m_timer.Elapsed += new ElapsedEventHandler(OnTimer);
                m_timer.AutoReset = bAutoReset;
                m_timer.Enabled = true;
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
                throw new tool.ETImpException(tool.LogTool.LOG_TYPE.ERROR, null, "定时器初始化失败");
            }
        }

        public void OnTimer(object source, ElapsedEventArgs e)
        {
            tool.Output.DumpWriteLine("@");
            m_flag = FLAG.TIME_OUT;
            _OnTimeOut();
        }

        public void EndTimer()
        {
            if (m_timer != null)
            {
                m_timer.Close();
                m_flag= FLAG.NONE;
                m_timer = null;
            }
        }

        public static string GetTimeComment()
        {
            string sTime = DateTime.Now.ToString(" yyyy-MM-dd HH:mm ");
            return "Writed Time: " + sTime;
        }
    }

    public class LogTool
    {
        public enum LOG_TYPE
        {
            ERROR,           //  程序运行错误
            EXCEPTION,       //  异常比错误级别低，不至于影响程序的运行
            TIME_OUT,        //  样张读取超时
            SHELL_BLOCK,     //  界面被阻塞
            NO_PASSWORD,     //  没有密码
            OPEN_FAILED,     //  文件打开失败
            FILE_ERROR,      //  样张文件存在错误
            BINARY_FAILED,   //  二进制打开失败
            INFO_ERROR,      //  addinfo.xml文件存在错误或操作失败
            TIME_UNACCEPTED, //  时间超过定义的浮动范围
            MEM_UNACCEPTED,  //  内存超过定义的浮动范围
            RESULT_ERROR,    //  重新计算结果,值不同
            UNKNOWN,         //  其他的问题
            MESSAGE,		 //	 自定义信息，如统计结果等
        }

        private const string _FILENAME = "FileName";
        private const string _MESSAGE = "Message";
        private const string _EX_MESSAGE = "EX_Message";
        private const string _EX_STACKTRACE = "EX_StackTrace";
        private const string UNKNOWN_Suffix = "unknown";
        private const string SUCCEED_NODE = "SUCCEED_MARK"; //  如果有这个标记，那么下次就不需要跑了
        private string m_sFileName;
        private string m_sRootName;
        private XmlDocument m_logXml = null;
        private XmlElement m_logRootNode = null;

        private static LogTool s_instance = null;

        public static LogTool GetInstance()
        {
            if(s_instance == null)
            {
                s_instance = new LogTool();
            }
            return s_instance;
        }

        public void AddSucceedMark()
        {
            try
            {
                XmlElement node = m_logXml.CreateElement("", SUCCEED_NODE, "");
                node.SetAttribute("TIME", CTimer.GetTimeComment());
                m_logRootNode.AppendChild(node);
            }
            catch (System.Exception ex)
            {
                tool.Output.DebugWriteLine("AddSucceedMark." + ex.Message);
            }
        }

        public static bool IsAnalysed(string sDir, string sToolName)
        {
            if(sDir == null)
            {
                return false;
            }
            CAddInfoHlp.ValidDirectory(ref sDir);
            string sLogFile = sDir + GetLogFileName(sToolName);
            if(!System.IO.File.Exists(sLogFile))
            {
                return false;
            }

            return IsExistSucceedNode(sLogFile, sToolName);
        }

        protected static bool IsExistSucceedNode(string sPath, string sRootName)
        {
            bool bRet = false;
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(sPath);
                XmlElement root = (XmlElement)doc.SelectSingleNode(sRootName);
                if(root != null)
                {
                    return true;
                }
            }
            catch (System.Exception ex)
            {
                tool.Output.DebugWriteLine("IsExistSucceedNode exception." + ex.Message);
            }
            return bRet;
        }

        protected static string GetLogFileName(string sToolName)
        {
            return "log_" + sToolName + ".xml";
        }

        protected string GetFileName(string sDir, string suffix)
        {
            string sFileName = GetLogFileName(suffix);
            if(sDir == null)
            {
                sDir = ET_Improve.Global.m_strDefaultDir;
            }

            tool.CAddInfoHlp.ValidDirectory(ref sDir);
            return sDir + sFileName;
        }

        protected void LoadLogFile()
        {
            try
            {
                m_logXml = new XmlDocument();
                m_logXml.Load(m_sFileName);
                m_logRootNode = (XmlElement)m_logXml.SelectSingleNode(m_sRootName);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }

        protected void CreateLogFile()
        {
            try
            {
                m_logXml = new XmlDocument();
                XmlDeclaration xmlDec = m_logXml.CreateXmlDeclaration("1.0", "UTF-8", null);
                m_logXml.InsertBefore(xmlDec, m_logXml.DocumentElement);

                m_logRootNode = m_logXml.CreateElement("", m_sRootName, "");
                m_logXml.AppendChild(m_logRootNode);
            }
            catch (System.Exception ex)
            {
            	throw ex;
            }
        }

        protected void InsertTimeComment()
        {
            XmlComment comment = m_logXml.CreateComment( CTimer.GetTimeComment() );
            m_logRootNode.AppendChild(comment);
        }

        public void BeginUseLog(string sDir, string suffix) 
        {
            try
            {
                if (suffix == null)
                {
                    throw new Exception("参数错误.suffix");
                }
                m_sRootName = suffix;
                m_sFileName = GetFileName(sDir, suffix);
                if(System.IO.File.Exists(m_sFileName))
                {
                    LoadLogFile();
                }
                else
                {
                    CreateLogFile();
                }
                InsertTimeComment();
            }
            catch(Exception ex)
            {
                m_logRootNode = null;
                m_logXml = null;
                throw ex;
            }
        }

        public void EndUseLog()
        {
            if (m_logXml == null)
            {
                tool.Output.DumpWriteLine("error: logTool.m_logXml == null");
                return;
            }
            try
            {
                m_logXml.Save(m_sFileName);
                m_logXml = null;
                s_instance = null;
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());
            }
        }

        // 如果不想要哪个参数，就传NULL
        public void AddLog(LOG_TYPE type, string sFileName, string sMsg, System.Exception ex)
        {
            try
            {
                Output.DumpWriteLine( string.Format("\n>##LOGTYPE:{0}##<", type.ToString()) );
                XmlElement node = m_logXml.CreateElement("", type.ToString(), "");
                if (sFileName != null)
                {
                    node.SetAttribute(_FILENAME, sFileName);
                }
                if (sMsg != null)
                {
                    node.SetAttribute(_MESSAGE, sMsg);
                }
                if(ex != null)
                {
                    node.SetAttribute(_EX_MESSAGE, ex.Message);
                    node.SetAttribute(_EX_STACKTRACE, ex.StackTrace.ToString());
                }
                m_logRootNode.AppendChild(node);
                if (type == LOG_TYPE.FILE_ERROR || type == LOG_TYPE.BINARY_FAILED ||
                    type == LOG_TYPE.OPEN_FAILED || type == LOG_TYPE.NO_PASSWORD ||
                    type == LOG_TYPE.TIME_OUT)
                {
                    System.Diagnostics.Debug.Assert(sFileName != null);
                    tool.CAddInfoHlp.AddFileIgnore(sFileName, ET_Improve.Global.s_curCmdName, type);
                }
            }
            catch (System.Exception exOut)
            {
                tool.Output.DumpWriteLine(">AddLog Exception:" + exOut.Message + "<");
                throw exOut;
            }
        }

        // 自定义log 类型必须为Message
        public void AddCustomLog(string[] sAttributes, string[] sValues)
        {
            try
            {
                XmlElement node = m_logXml.CreateElement("", tool.LogTool.LOG_TYPE.MESSAGE.ToString(), "");
                for (int i = 0; i < sAttributes.Length; ++i)
                {
                    string sVal = "";
                    if (i < sValues.Length)
                    {
                        sVal = sValues[i];
                    }

                    node.SetAttribute(sAttributes[i], sVal);
                }
                m_logRootNode.AppendChild(node);
            }
            catch (System.Exception ex)
            {
                tool.Output.DumpWriteLine(ex.ToString());	
            }
        }
    }

    // 操作文件相关
    public class CAddInfoHlp
    {
        public enum ADD_INFO_OP
        {
            PASSWORD,   // 文件密码
            IGNORE,     // 忽略文件
        }

        public class CFileInfo
        {
            public string FileName { set; get; }
            public string Password { set; get; }
            public CFileInfo() {}
            public CFileInfo(string _Name, string _password)
            {
                FileName = _Name;
                Password = _password;
            }
        }

        public class CAddtionInfo
        {
            private List<string> m_ignoreCmd = new List<string>();
            public string FileName { set; get; }
            public string Password { set; get; }

            // 合法性判断
            protected bool IsCmdNameValid(string _cmdName)
            {
                foreach (suit_base.SuiteBase x in suit_base.SuiteBase.GetSuitClasses())
                {
                    if (x.GetCommand() == _cmdName)
                    {
                        return true;
                    }
                }
                return false;
            }

            public bool IsIgnore(string _cmdName)
            {
                if(!IsCmdNameValid(_cmdName))
                {
                    return false;
                }

                foreach (string s in m_ignoreCmd)
                {
                    if(s.Equals(_cmdName))
                    {
                        return true;
                    }
                }
                return false;
            }

            public void AddIgnore(string _cmdName)
            {
                if (!IsCmdNameValid(_cmdName))
                {
                    return;
                }
                m_ignoreCmd.Add(_cmdName);
            }
        }

        private const string ADDINFO_ROOT = "root";
        private const string ADDINFO_INFO = "AddInfo";
        private const string ADDINFO_NAME = "FileName";
        private const string ADDINFO_PASSWORD = "PASSWORD";
        private const string ADDINFO_IGNORE = "IGNORE";

        public static void ValidDirectory(ref string sDir)
        {
            if (!sDir[sDir.Length - 1].Equals(@"\"))
            {
                sDir += @"\";
            }
        }

        // 参数:sFile文件名；sCmdName被发现的工具；causeType原因
        public static void AddFileIgnore(string sFile, string sCmdName, LogTool.LOG_TYPE causeType)
        {
            try
            {
                string sFileName = System.IO.Path.GetFileName(sFile);
                string sInfoFile = System.IO.Path.GetDirectoryName(sFile);
                // 排除临时文件夹的文件
                if (sInfoFile.Equals(System.IO.Path.GetTempPath()))
                {
                    return;
                }
                sInfoFile += "\\addinfo.xml";
                XmlDocument doc = new XmlDocument();
                System.Xml.XmlElement rootNode = null;
                if (!System.IO.File.Exists(sInfoFile))
                {
                    XmlDeclaration xmlDec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                    doc.InsertBefore(xmlDec, doc.DocumentElement);

                    rootNode = doc.CreateElement("", ADDINFO_ROOT, "");
                    doc.AppendChild(rootNode);
                }
                else
                {
                    doc.Load(sInfoFile);
                    rootNode = (XmlElement)doc.SelectSingleNode(ADDINFO_ROOT);
                }
                DoAddInfoElement(sFileName, doc, rootNode, sCmdName, causeType);
                doc.Save(sInfoFile);
            }
            catch (System.Exception ex)
            {
                LogTool.GetInstance().AddLog(LogTool.LOG_TYPE.INFO_ERROR, sFile, null, ex);
            }
        }

        protected static void DoAddInfoElement(string sFileName, XmlDocument doc, XmlElement rootNode,
                string cmdName, LogTool.LOG_TYPE logType)
        {
            // 是否已经存在该节点
            string sFind = String.Format("{0}/{1}[@{2}='{3}']", ADDINFO_ROOT, ADDINFO_INFO,
                                            ADDINFO_NAME, sFileName);
            XmlNode node = doc.SelectSingleNode(sFind);
            // 是否存在文件记录
            if (node != null)
            {
                XmlElement xe = (XmlElement)node;
                DoIgnoreElement(doc, rootNode, xe, cmdName, logType);
            }
            else
            {
                XmlElement xe = doc.CreateElement(ADDINFO_INFO);
                xe.SetAttribute(ADDINFO_NAME, sFileName);
                DoIgnoreElement(doc, rootNode, xe, cmdName, logType);
            }
        }

        protected static void DoIgnoreElement(XmlDocument doc, XmlElement rootNode,
                XmlElement addInfoNode, string cmdName, LogTool.LOG_TYPE logType)
        {
            XmlNodeList xnl2 = addInfoNode.ChildNodes;
            if (xnl2.Count == 0)
            {
                XmlElement xeIgnore = doc.CreateElement(ADDINFO_IGNORE);
                xeIgnore.SetAttribute(cmdName, logType.ToString());
                addInfoNode.AppendChild(xeIgnore);
            }
            else
            {
                XmlElement xeIgnore = (XmlElement)xnl2.Item(0);
                xeIgnore.SetAttribute(cmdName, logType.ToString());
            }
            rootNode.AppendChild(addInfoNode);
        }

        // 在_cmdName下忽略的文件是不会被加入的
        public static Dictionary<string, List<CFileInfo>> GetFolderFiles(string sDir, string _cmdName)
        {
            Dictionary<string, List<CFileInfo>> fileDic = new Dictionary<string, List<CFileInfo>>();
            HashSet<string> filter = new HashSet<string>();
            filter.Add(".xls");
            filter.Add(".et");
            Traverse(sDir, fileDic, _cmdName, filter);
            return fileDic;
        }

        public static Dictionary<string, List<CFileInfo>> GetFolderFiles(string sDir, string _cmdName, string sFilter)
        {
            Dictionary<string, List<CFileInfo>> fileDic = new Dictionary<string, List<CFileInfo>>();
            HashSet<string> filter = new HashSet<string>();
            string[] sFilters = sFilter.Split('|');
            foreach (string s in sFilters)
            {
                if(!filter.Contains(s))
                {
                    filter.Add(s);
                }
            }
            Traverse(sDir, fileDic, _cmdName, filter);
            return fileDic;
        }

        protected static void Traverse(string sDir, Dictionary<string, List<CFileInfo>> fileDic, string _cmdName, HashSet<string> filter)
        {
            System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(sDir);
            if (dirInfo == null)
            {
                return;
            }
            foreach (System.IO.DirectoryInfo d in dirInfo.GetDirectories())
            {
                Traverse(sDir + @"\" + d.ToString(), fileDic, _cmdName, filter);
            }

            List<CFileInfo> tmpFiles = new List<CFileInfo>();
            List<CAddtionInfo> addInfoList = GetAddtionInfos(sDir);

            foreach (System.IO.FileInfo f in dirInfo.GetFiles("*.*"))
            {
                string sFile = sDir + @"\" + f.ToString();
                string sExt = System.IO.Path.GetExtension(sFile);
                if(!filter.Contains(sExt))
                {
                    continue;
                }
                
                CAddtionInfo addInfo = null;
                if(addInfoList != null)
                {
                    addInfo = GetFileAddinfo(addInfoList, f.ToString());
                }
                
                if(addInfo != null && addInfo.IsIgnore(_cmdName))
                {
                    continue;
                }
                CFileInfo fi = new CFileInfo();
                fi.FileName = sDir + @"\" + f.ToString();
                if (addInfo != null)
                {
                    fi.Password = addInfo.Password;
                }
                tmpFiles.Add(fi);   
            }

            fileDic.Add(sDir, tmpFiles);
        }

        protected static List<CAddtionInfo> GetAddtionInfos(string sDir)
        {
            try
            {
                List<CAddtionInfo> retLst = null;
                CAddInfoHlp.ValidDirectory(ref sDir);
                string sInfoName = sDir + "addinfo.xml";
                if (!System.IO.File.Exists(sInfoName))
                {
                    return retLst;
                }
                retLst = new List<CAddtionInfo>();
                XmlDocument doc = new XmlDocument();
                doc.Load(sInfoName);
                XmlNodeList xnl = doc.SelectSingleNode(ADDINFO_ROOT).ChildNodes;
                foreach (XmlNode node in xnl)
                {
                    if(node.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }
                    if(node.Name != ADDINFO_INFO)
                    {
                        continue;
                    }
                    CAddtionInfo ai = new CAddtionInfo();
                    XmlElement xe = (XmlElement)node;
                    string sVal = xe.GetAttribute(ADDINFO_NAME);
                    ai.FileName = sVal;
                    sVal = xe.GetAttribute(ADDINFO_PASSWORD);
                    if (sVal.Length > 0)
                    {
                        ai.Password = sVal;
                    }
                    CheckIgnore(xe, ai);
                    
                    retLst.Add(ai);
                }
                return retLst;
            }
            catch (System.Exception ex)
            {
                LogTool.GetInstance().AddLog(LogTool.LOG_TYPE.INFO_ERROR, null, "Dir:" + sDir, ex);
            }
            return null;
        }

        public static bool IsIgnore(string sDir, string sFileName, string _cmdName)
        {
            List<CAddtionInfo> retLst = GetAddtionInfos(sDir);
            if(retLst == null)
            {
                return false;
            }

            foreach (CAddtionInfo ai in retLst)
            {
                if(ai.FileName == sFileName)
                {
                    return ai.IsIgnore(_cmdName);
                }
            }
            return false;
        }

        protected static void CheckIgnore(XmlElement node, CAddtionInfo ai)
        {
            XmlNodeList xnlSub = node.ChildNodes;
            if (xnlSub.Count == 0)
            {
                return;
            }
            XmlElement xeIgnore = (XmlElement)xnlSub.Item(0);
            XmlNamedNodeMap attrMap = xeIgnore.Attributes;
            if(attrMap == null)
            {
                return;
            }
            // 只要有一个属性且值不为空就认为是忽略的
            for (int i = 0; i < attrMap.Count; ++i)
            {
                XmlAttribute attr = (XmlAttribute)attrMap.Item(i);
                if(attr.Value.Length  > 0)
                {
                    ai.AddIgnore(attr.Value);
                }
            }
        }

        protected static CAddtionInfo GetFileAddinfo(List<CAddtionInfo> aiList, string sFileName)
        {
            for (int i = 0; i < aiList.Count; ++i)
            {
                if( aiList[i].FileName == sFileName)
                {
                    return aiList[i];
                }
            }
            return null;
        }
    }

    // 操纵临时文件
    public class CTmpFileHlp
    {
        internal static List<string> tmpFile = new List<string>();
        public static void AddTmpFile(string sFileName)
        {
            tmpFile.Add(sFileName);
        }

        public static void Clear()
        {
            int i = 0;
            while(i < tmpFile.Count)
            {
                try
                {
                    System.IO.File.Delete(tmpFile[i]);
                    tmpFile.RemoveAt(i);
                }
                catch (System.Exception ex)
                {
                    ++i;
                    tool.Output.DumpWriteLine(ex.Message);
                }
            }
        }

        public static void DeleteTmpFile(string sFile)
        {
            if (sFile != null)
            {
                tmpFile.Add(sFile);
            }
            Clear();
        }

        // 返回临时文件夹的一个文件名
        public static string GetSystemTmpName(string srcName)
        {
            // 系统临时文件夹
            string tempPath = System.IO.Path.GetTempPath();
            return CTmpFileHlp.GetValidPathName(tempPath, srcName);
        }

        public static string GetLocalTmpName(string srcName)
        {
            string sDir = System.IO.Path.GetDirectoryName(srcName);
            CAddInfoHlp.ValidDirectory(ref sDir);
            return CTmpFileHlp.GetValidPathName(sDir, srcName);
        }

        protected static string GetValidPathName(string sDstPath, string sFilePath)
        {
            string fileNameWithoutExt =
                   System.IO.Path.GetFileNameWithoutExtension(sFilePath);
            string fileExt = System.IO.Path.GetExtension(sFilePath);
            string sDstName = sDstPath + System.IO.Path.GetFileName(sFilePath);
            int i = 0;
            while (System.IO.File.Exists(sDstName))
            {
                sDstName = sDstPath + fileNameWithoutExt +
                           string.Format("_({0})", ++i) + fileExt;
            }
            return sDstName;
        }
    }

    // 如果不需要某一项可置为null
    public class ETImpException : Exception
    {
        public string FileName
        {
            get;
            set;
        }
        public LogTool.LOG_TYPE LogType
        {
            get;
            set;
        }
        private string m_Message = null;
        private System.Exception m_innerEx;


        public ETImpException(LogTool.LOG_TYPE type, string sFileName, string sMsg)
            : base(sMsg)
        {
            LogType = type;
            FileName = sFileName;
            m_Message = sMsg;
        }

        public ETImpException(LogTool.LOG_TYPE type, string sFileName, string sMsg, Exception inner)
            : base(sMsg, inner)
        {
            LogType = type;
            FileName = sFileName;
            m_innerEx = inner;
            m_Message = sMsg;
        }

        public void AddLog()
        {
            LogTool.GetInstance().AddLog(LogType, FileName, m_Message, m_innerEx);
        }

        public void Display()
        {
            string sDisp;
            sDisp = "#logType:" + LogType.ToString();
            if (FileName != null)
            {
                sDisp += "#FileName:" + FileName;
            }
            if(m_Message != null)
            {
                sDisp += "#Message:" + m_Message;
            }
            if (m_innerEx != null)
            {
                sDisp += "#InnerException:" + m_innerEx.ToString();
            }
            tool.Output.DumpWriteLine(sDisp);
        }
    }

    public static class ConfigReader
    {
        public static XmlNodeList GetElementList(String strEleName)
        {
            String strCfgPath = ET_Improve.Global.sConfigFile;
            if (!System.IO.File.Exists(strCfgPath))
            {
                string tmp = Process.GetCurrentProcess().MainModule.FileName;
                //往上跳两级，调试用
                tmp = Path.GetDirectoryName(tmp);
                tmp = Path.GetDirectoryName(tmp);
                tmp = Path.GetDirectoryName(tmp);
                strCfgPath = tmp + "\\" + strCfgPath;
                if (!System.IO.File.Exists(strCfgPath))
                {
                    throw new Exception("config.xml not find!");
                }
            }

            XmlDocument doc = new XmlDocument();
            doc.Load(strCfgPath);
            ET_Improve.Global.sConfigFile = strCfgPath;
            XmlElement docEle = doc.DocumentElement;
            foreach (XmlNode ele in docEle.ChildNodes)
            {
                if (ele.Name.ToUpper() == strEleName.ToUpper())
                {
                    return ele.ChildNodes;
                }
            }

            throw new Exception("suite xml config not find!");
        }
    }

    public class Output
    {
        // Begin Dump文件
        private System.IO.StreamWriter m_sw;
        private string m_sDumpFile;
        private int m_nCurLine;
        private int m_nPart;
        private const int MAX_LINE = 8000;
        private static Output s_dump = new Output();

        public static Output GetInstance()
        {
            return s_dump;
        }

        public void BeginDumpFile(string sDumpPath)
        {
            string sFileName = DateTime.Now.ToString("yyyy-MM-dd_HH-mm");
            sFileName = "dump_" + sFileName;
            if (sDumpPath == null)
            {
                sDumpPath = ET_Improve.Global.m_strDefaultDir;
            }

            CAddInfoHlp.ValidDirectory(ref sDumpPath);
            m_sDumpFile = sDumpPath + sFileName;
            m_nPart = 0;
            BeginDumpFile();
        }

        protected void BeginDumpFile()
        {
            try
            {
                m_nCurLine = 0;
                string sFileName = m_sDumpFile;
                if (m_nPart > 0)
                {
                    sFileName += string.Format("_add{0}", m_nPart);
                }
                m_sw = File.AppendText(sFileName);
                m_sw.AutoFlush = true;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
                throw ex;
            }
        }

        public void EndDumpFile()
        {
            if(m_sw == null)
            {
                return;
            }
            try
            {
                m_sw.Close();
                m_sw = null;
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
                throw ex;
            }
        }

        public void Dump(string str)
        {
            Dump(str, false);
        }

        public void DumpLine(string str)
        {
            Dump(str, true);
        }

        protected void Dump(string str, bool bWriteLine)
        {
            if (m_sw == null)
            {
                tool.Output.DebugWriteLine("m_sw == null");
                return;
            }

            if (bWriteLine)
            {
                ++m_nCurLine;
                m_sw.WriteLine(str);
            }
            else
            {
                m_sw.Write(str);
            }

            if (m_nCurLine >= MAX_LINE)
            {
                EndDumpFile();
                ++m_nPart;
                BeginDumpFile();
            }
        }

        //// End Dump File
        
        public static void DumpWrite(string str)
        {
            Console.Write(str);
        }

        public static void DumpWriteLine()
        {
            Console.WriteLine();
        }

        public static void DumpWriteLine(string str)
        {
            Console.WriteLine(str);
        }

        public static void DebugWriteLine(string str)
        {
#if DEBUG
            Console.WriteLine(str);
#endif
        }
    }
}